package com.jckj.core.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.jckj.core.annotation.MyBatisDao;
import com.jckj.core.db.DynamicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author liuzhiyuan
 * spring jdbc config class
 * Created by zhiyuan on 2017/12/23.
 */
@Configuration
@PropertySource(value = {"classpath:/jdbc.properties"})
@MapperScan(basePackages = "com.jckj.*.dao")
@EnableTransactionManagement
public class JdbcConfig implements TransactionManagementConfigurer{

    private Logger logger  = LoggerFactory.getLogger(JdbcConfig.class);

    @Autowired
    Environment env;

    @Bean
    public PlatformTransactionManager transactionManager(){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource());

        return transactionManager;
    }

    private DataSource getDataSource(String driverClass, String url, String username, String password){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClass);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setInitialSize(1);
        dataSource.setMaxActive(20);
        dataSource.setMinIdle(1);
        dataSource.setMaxWait(60000);
        dataSource.setValidationQuery("SELECT 'x' FROM DUAL");
        dataSource.setTimeBetweenEvictionRunsMillis(60000);
        dataSource.setMinEvictableIdleTimeMillis(60000);
        dataSource.setTestWhileIdle(true);
        dataSource.setTestOnReturn(true);
        dataSource.setTestOnBorrow(true);
        try {
            dataSource.setFilters("stat");
        }catch(Exception ex){
            logger.error(ex.getMessage());
        }
        return dataSource;
    }

    @Bean(initMethod = "init", destroyMethod = "close")
    public DataSource masterDataSource(){
        return getDataSource(env.getProperty("master.jdbc.driver"), env.getProperty("master.jdbc.url"), env.getProperty("master.jdbc.username"), env.getProperty("master.jdbc.password"));
    }

    @Bean(initMethod = "init", destroyMethod = "close")
    public DataSource slaveDataSource(){
        return getDataSource(env.getProperty("slave.jdbc.driver"), env.getProperty("slave.jdbc.url"), env.getProperty("slave.jdbc.username"), env.getProperty("slave.jdbc.password"));
    }

    @Bean
    public DataSource dataSource(){
        DynamicDataSource dataSource = new DynamicDataSource();
        Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
        targetDataSources.put("masterDataSource", masterDataSource());
        targetDataSources.put("slaveDataSource", slaveDataSource());
        dataSource.setTargetDataSources(targetDataSources);
        dataSource.setDefaultTargetDataSource(masterDataSource());
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource());
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mappers/*.xml"));
        sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
        return sqlSessionFactoryBean.getObject();
    }

    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return transactionManager();
    }
}
